/**
 * API client for multi-page chat application
 */
export class ApiClient {
    constructor(baseUrl = '') {
        this.baseUrl = baseUrl;
        this.defaultHeaders = {
            'Content-Type': 'application/json'
        };
    }

    /**
     * Make a generic HTTP request
     */
    async request(endpoint, options = {}) {
        const url = `${this.baseUrl}${endpoint}`;
        const config = {
            method: 'GET',
            headers: { ...this.defaultHeaders },
            ...options
        };

        // Add request body if provided
        if (config.body && typeof config.body === 'object') {
            config.body = JSON.stringify(config.body);
        }

        try {
            const response = await fetch(url, config);
            
            // Parse response
            let data;
            const contentType = response.headers.get('content-type');
            if (contentType && contentType.includes('application/json')) {
                data = await response.json();
            } else {
                data = await response.text();
            }

            // Handle HTTP errors
            if (!response.ok) {
                const error = new Error(data.error || data.message || `HTTP ${response.status}`);
                error.status = response.status;
                error.response = data;
                throw error;
            }

            return data;
        } catch (error) {
            if (error.name === 'TypeError' && error.message.includes('fetch')) {
                // Network error
                throw new Error('Unable to connect to server. Please check your internet connection.');
            }
            throw error;
        }
    }

    /**
     * GET request
     */
    async get(endpoint, params = {}) {
        const url = new URL(endpoint, window.location.origin);
        Object.keys(params).forEach(key => {
            if (params[key] !== undefined && params[key] !== null) {
                url.searchParams.append(key, params[key]);
            }
        });

        return this.request(url.pathname + url.search);
    }

    /**
     * POST request
     */
    async post(endpoint, body = {}) {
        return this.request(endpoint, {
            method: 'POST',
            body
        });
    }

    /**
     * PUT request
     */
    async put(endpoint, body = {}) {
        return this.request(endpoint, {
            method: 'PUT',
            body
        });
    }

    /**
     * DELETE request
     */
    async delete(endpoint) {
        return this.request(endpoint, {
            method: 'DELETE'
        });
    }

    /**
     * Health check endpoint
     */
    async healthCheck() {
        try {
            const response = await fetch('/api/stats');
            return response.ok;
        } catch (error) {
            return false;
        }
    }
}

/**
 * Room-specific API methods
 */
export class RoomAPI extends ApiClient {
    /**
     * Create a new room
     */
    async createRoom(roomData) {
        const { name, password, maxUsers, creatorNickname } = roomData;
        
        return this.post('/api/rooms', {
            name: name.trim(),
            password: password || null,
            maxUsers: parseInt(maxUsers) || 50,
            creatorNickname: creatorNickname.trim()
        });
    }

    /**
     * Get room information
     */
    async getRoomInfo(roomId) {
        if (!roomId) {
            throw new Error('Room ID is required');
        }

        return this.get(`/api/rooms/${roomId}`);
    }

    /**
     * Join a room
     */
    async joinRoom(roomId, userData) {
        const { nickname, password } = userData;
        
        if (!roomId) {
            throw new Error('Room ID is required');
        }

        return this.post(`/api/rooms/${roomId}/join`, {
            nickname: nickname.trim(),
            password: password || null
        });
    }

    /**
     * Validate an invite code
     */
    async validateInvite(inviteCode) {
        if (!inviteCode) {
            throw new Error('Invite code is required');
        }

        return this.get(`/api/invite/${inviteCode}`);
    }

    /**
     * Validate session
     */
    async validateSession(roomId, userId, sessionToken) {
        return this.post('/api/validate-session', {
            roomId,
            userId,
            sessionToken
        });
    }

    /**
     * Get server statistics
     */
    async getStats() {
        return this.get('/api/stats');
    }
}

/**
 * Connection monitoring utility
 */
export class ConnectionMonitor {
    constructor() {
        this.isOnline = navigator.onLine;
        this.listeners = [];
        this.api = new ApiClient();
        
        this.setupEventListeners();
    }

    setupEventListeners() {
        window.addEventListener('online', () => {
            this.isOnline = true;
            this.notifyListeners('online');
        });

        window.addEventListener('offline', () => {
            this.isOnline = false;
            this.notifyListeners('offline');
        });
    }

    addListener(callback) {
        this.listeners.push(callback);
    }

    removeListener(callback) {
        this.listeners = this.listeners.filter(listener => listener !== callback);
    }

    notifyListeners(status) {
        this.listeners.forEach(callback => {
            try {
                callback(status, this.isOnline);
            } catch (error) {
                console.error('Error in connection listener:', error);
            }
        });
    }

    async checkServerConnection() {
        try {
            const isHealthy = await this.api.healthCheck();
            return isHealthy;
        } catch (error) {
            return false;
        }
    }
}

/**
 * Utility functions for API calls
 */
export class ApiUtils {
    /**
     * Request timeout wrapper
     */
    static withTimeout(promise, timeoutMs = 10000) {
        return Promise.race([
            promise,
            new Promise((_, reject) => {
                setTimeout(() => {
                    reject(new Error(`Request timeout after ${timeoutMs}ms`));
                }, timeoutMs);
            })
        ]);
    }

    /**
     * Retry wrapper for API calls
     */
    static async withRetry(apiCall, maxRetries = 3, delay = 1000) {
        let lastError;
        
        for (let attempt = 1; attempt <= maxRetries; attempt++) {
            try {
                return await apiCall();
            } catch (error) {
                lastError = error;
                
                // Don't retry for client errors (4xx)
                if (error.status >= 400 && error.status < 500) {
                    throw error;
                }
                
                // Don't retry on last attempt
                if (attempt === maxRetries) {
                    break;
                }
                
                // Wait before retry with exponential backoff
                await new Promise(resolve => setTimeout(resolve, delay * Math.pow(2, attempt - 1)));
            }
        }
        
        throw lastError;
    }

    /**
     * Validate input data
     */
    static validateRoomName(name) {
        if (!name || typeof name !== 'string') return false;
        const trimmed = name.trim();
        return trimmed.length >= 1 && trimmed.length <= 50;
    }

    static validateNickname(nickname) {
        if (!nickname || typeof nickname !== 'string') return false;
        const trimmed = nickname.trim();
        return trimmed.length >= 1 && trimmed.length <= 30;
    }

    static validateRoomId(roomId) {
        if (!roomId || typeof roomId !== 'string') return false;
        return roomId.length >= 6 && /^[a-zA-Z0-9]+$/.test(roomId);
    }
}

// Export global instances
export const api = new ApiClient();
export const roomAPI = new RoomAPI();
export const connectionMonitor = new ConnectionMonitor();